//
//  XMPPManager.m
//  MyChatDemo
//
//  Created by DragonYao on 2017/9/12.
//  Copyright © 2017年 DragonYao. All rights reserved.
//

#import "XMPPManager.h"

@interface XMPPManager ()<XMPPStreamDelegate> {
    
    XMPPvCardCoreDataStorage *_vCartStorage;//电子卡片存储数据库
    XMPPvCardAvatarModule *_avatorModule;//头像模块
    XMPPResultBlock _resultBlock;
    XMPPReconnect *_reconnect;//自动链接模块
}
//初始化
- (void)setupXMPPStream;
//连接到服务器
- (void)connectToHosts;
//发送密码到服务器
- (void)sendPasswordToHost;
//发送在线消息
- (void)sendOnlineToHost;

@end

@implementation XMPPManager

- (void)dealloc {
    [self tearsDown];
}

+ (XMPPManager *)sharedManager {
    static XMPPManager *_singleManager = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _singleManager = [[[self class] alloc] init];
    });
    return _singleManager;
}

#pragma mark - Helper Methods
- (void)setupXMPPStream {
    
    /**
     *  注意：每使用一个模块，都要激活
     */
    
    _xmppStream = [[XMPPStream alloc] init];
    
    /*接入流管理模块，用于流恢复跟消息确认，在移动端很重要*/
    _managementMemoryStorage = [[XMPPStreamManagementMemoryStorage alloc] init];
    _xmppManagement = [[XMPPStreamManagement alloc] initWithStorage:_managementMemoryStorage];
    _xmppManagement.autoResume = YES;
    [_xmppManagement activate:_xmppStream];
    
    /*电子名片模块*/
    _vCartStorage = [XMPPvCardCoreDataStorage sharedInstance];
    _vCartModule = [[XMPPvCardTempModule alloc] initWithvCardStorage:_vCartStorage];
    [_vCartModule activate:_xmppStream];//激活电子名片
    /*头像模块*/
    _avatorModule = [[XMPPvCardAvatarModule alloc] initWithvCardTempModule:_vCartModule];//
    [_avatorModule activate:_xmppStream];//激活模块
    /*添加自动连接模块*/
    _reconnect = [[XMPPReconnect alloc] init];
    [_reconnect activate:_xmppStream];
    /*花名册【好友列表】模块*/
    _rosterStorage = [[XMPPRosterCoreDataStorage alloc] init];
    _roster = [[XMPPRoster alloc] initWithRosterStorage:_rosterStorage];
    [_roster activate:_xmppStream];//激活模块
    
    /*发送消息模块*/
    _msgStorage = [[XMPPMessageArchivingCoreDataStorage alloc] init];
    _msgArvhiving = [[XMPPMessageArchiving alloc] initWithMessageArchivingStorage:_msgStorage];
    [_msgArvhiving activate:_xmppStream];//激活
    
    [_xmppStream addDelegate:self delegateQueue:dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)];
}

- (void)connectToHosts {
    
    if (!_xmppStream) {
        [self setupXMPPStream];
    }
    SLog(@"\n正在连接服务器...");
    [self postNotification:XMPPResultTypeLoginConnecting];
    //这个得从沙河下面获取
    NSString *userID = @"";
    if (self.isRegisterOption) {
        userID = [UserLocalInfo sharedUserInfo].userRegisterId;
    }
    else {
        userID = [UserLocalInfo sharedUserInfo].userId;
    }
    //设置JID
    _xmppStream.myJID = [XMPPJID jidWithUser:userID domain:kLoginDomain resource:@"iPhone"];
    //设置域名
    _xmppStream.hostName = kLoginDomain;//可以是域名 也可以是IP地址
    //端口 默认5222
    _xmppStream.hostPort = kDomainPort;
    
    //如果之前连接的一次服务器，不去断开的话，会报已经连接主机的错误
    [_xmppStream disconnect];
    
    NSError *error = nil;
    BOOL isSuccess = [_xmppStream connectWithTimeout:XMPPStreamTimeoutNone error:&error];
    if (!isSuccess) {
        SLog(@"connection error : %@", error);
    }
}

- (void)sendPasswordToHost {
    SLog(@"\n正在密码授权...");
    NSString *pwd = [UserLocalInfo sharedUserInfo].userPwd;
    NSError *error = nil;
    [_xmppStream authenticateWithPassword:pwd error:&error];
    if (error) {
        SLog(@"authenticate error: %@", error);
    }
}

- (void)sendOnlineToHost {
    SLog(@"\n发送在线状态");
    XMPPPresence *presence = [XMPPPresence presence];
    [_xmppStream sendElement:presence];
}

//断开与服务器的连接
- (void)userLogout {
    self.registerOption = NO;
    //1、发送离线消息
    XMPPPresence *logout = [XMPPPresence presenceWithType:@"unavailable"];
    [_xmppStream sendElement:logout];
    //2、断开连接
    [_xmppStream disconnect];
    //3、回到登录的控制器
    [SLUtils showInitialViewWithStoryboard:@"Login"];
    [UserLocalInfo sharedUserInfo].hasLogin = NO;
}

- (void)userLogin:(XMPPResultBlock)resultBlock {
    _resultBlock = resultBlock;
    [self connectToHosts];
}

- (void)userRegitser:(XMPPResultBlock)resultBlock  {
    _resultBlock = resultBlock;
    [self connectToHosts];
}

/**
 *  发送通知
 */
- (void)postNotification:(XMPPResultType)resultType {
    [[NSNotificationCenter defaultCenter] postNotificationName:kUserLoginStatusNotification object:nil userInfo:@{@"LoginStatus":@(resultType)}];
}

- (void)tearsDown {
    //清除代理
    [_xmppStream removeDelegate:self];
    //停止模块
    [_reconnect deactivate];
    [_vCartModule deactivate];
    [_avatorModule deactivate];
    [_roster deactivate];
    [_msgArvhiving deactivate];
    [_xmppManagement deactivate];
    //断开连接
    [_xmppStream disconnect];
    //释放资源
    _reconnect = nil;
    _vCartStorage = nil;
    _vCartModule = nil;
    _avatorModule = nil;
    _roster = nil;
    _msgArvhiving = nil;
    _msgStorage = nil;
    _rosterStorage = nil;
    _xmppManagement = nil;
    _managementMemoryStorage = nil;
    _xmppStream = nil;
}

#pragma mark - XMPPStreamDelegate
- (void)xmppStreamDidConnect:(XMPPStream *)sender {
    
    if (self.isRegisterOption) {
        SLog(@"\n服务器连接成功，发送注册密码");
        //发送注册密码
        [_xmppStream registerWithPassword:[UserLocalInfo sharedUserInfo].userRegisterPwd error:nil];
    }
    else {
        SLog(@"\n服务器连接成功，发送登录密码");
        //主机连接成功，发送密码授权
        [self sendPasswordToHost];
    }
}

- (void)xmppStreamDidDisconnect:(XMPPStream *)sender withError:(NSError *)error {
    if (error && _resultBlock) {
        _resultBlock(XMPPResultTypeNetError);
    }
    if (error) {
        [self postNotification:XMPPResultTypeNetError];
    }
    SLog(@"\n与服务器断连接： %@", error);
}

//密码授权
- (void)xmppStreamDidAuthenticate:(XMPPStream *)sender {
    SLog(@"\n密码授权成功!");
    [self sendOnlineToHost];
    if (_resultBlock) {
        _resultBlock(XMPPResultTypeLoginSuccess);
    }
    [self postNotification:XMPPResultTypeLoginSuccess];
    [_xmppManagement enableStreamManagementWithResumption:YES maxTimeout:0];
}

- (void)xmppStream:(XMPPStream *)sender didNotAuthenticate:(DDXMLElement *)error {
    if (_resultBlock) {
        _resultBlock(XMPPResultTypeLoginFailure);
    }
    SLog(@"\n密码授权失败：%@", error);
    [self postNotification:XMPPResultTypeLoginFailure];
}

/**
 *  接受到通知
 */
- (void)xmppStream:(XMPPStream *)sender didReceiveMessage:(XMPPMessage *)message {
    dispatch_async(dispatch_get_main_queue(), ^{
        if ([UIApplication sharedApplication].applicationState != UIApplicationStateActive) {
            //本地通知
            UILocalNotification *localNoti = [[UILocalNotification alloc] init];
            //设置内容
            localNoti.alertBody = [NSString stringWithFormat:@"%@ \n %@", message.fromStr, message.body];
            //什么时候执行，立即执行
            localNoti.fireDate = [NSDate date];
            //声音
            localNoti.soundName = @"default";
            
            //执行
            [[UIApplication sharedApplication] scheduleLocalNotification:localNoti];
        }
    });
}

//注册
- (void)xmppStreamDidRegister:(XMPPStream *)sender {
    SLog(@"注册成功");
    if (_resultBlock) {
        _resultBlock(XMPPResultTypeRegisterSuccess);
    }
}

- (void)xmppStream:(XMPPStream *)sender didNotRegister:(DDXMLElement *)error {
    SLog(@"注册失败 %@", error);
    if (_resultBlock) {
        _resultBlock(XMPPResultTypeRegisterFailure);
    }
}


@end
